"""
Mercari API 客户端工具
提供对Mercari商品搜索API的封装
"""

import requests
import json
import time
import hashlib
from typing import Dict, Optional, List
from datetime import datetime
from .logger import get_monitor_logger, log_function_call, log_async_function_call
from .traffic_monitor import traffic_monitor
from .user_agent_manager import default_ua_manager

try:
    from .dpop_token_generator import get_fresh_mercari_token, is_mercari_token_expired
    DPOP_GENERATOR_AVAILABLE = True
except ImportError:
    DPOP_GENERATOR_AVAILABLE = False
    print("⚠️ DPoP Token 生成器不可用，将使用静态 Token")

# 获取监控日志器 
monitor_logger = get_monitor_logger()


class MercariAPI:
    """
    Mercari API 客户端
    封装了DPoP_TOKEN和请求信息，只需传入keyword即可搜索
    """
    
    def __init__(self, user_agent: Optional[str] = None, dpop_token: Optional[str] = None, auto_refresh_token: bool = True, use_random_ua: bool = True):
        """
        初始化Mercari API客户端

        Args:
            user_agent: 自定义User-Agent，可选（如果提供则不使用随机UA）
            dpop_token: 自定义DPoP令牌，可选
            auto_refresh_token: 是否自动刷新DPoP令牌，默认True
            use_random_ua: 是否使用随机User-Agent，默认True
        """
        self.base_url = 'https://api.mercari.jp'
        self.auto_refresh_token = auto_refresh_token
        self.use_random_ua = use_random_ua and user_agent is None  # 只有在没有指定UA时才使用随机UA

        # 初始化 DPoP Token
        if dpop_token:
            self.dpop_token = dpop_token
            monitor_logger.info("🔧 使用手动指定的 DPoP Token")
        elif DPOP_GENERATOR_AVAILABLE and auto_refresh_token:
            monitor_logger.info("🔄 使用自动生成的 DPoP Token")
            self.dpop_token = get_fresh_mercari_token()
        else:
            # 使用默认的静态 Token（兜底方案）
            self.dpop_token = 'eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7ImNydiI6IlAtMjU2Iiwia3R5IjoiRUMiLCJ4IjoiNlQ5OUNNWUozY2drMDkzbzJLajI3akxNTUItcHUyTHZKbzNNUXN1VWduUSIsInkiOiJYY1A4ODJsRUJiakNIeGZscEZfWUVBSE1kS3Z2RGtzY2g0YUU3V3I4NGRFIn19.eyJpYXQiOjE3NTI0ODIwOTMsImp0aSI6IjFjOTUxM2MwLTY5Y2MtNDY2My04OWJmLTQzNjdiNGFhOGZiNiIsImh0dSI6Imh0dHBzOi8vYXBpLm1lcmNhcmkuanAvdjIvZW50aXRpZXM6c2VhcmNoIiwiaHRtIjoiUE9TVCIsInV1aWQiOiIxZGRkZmYyNy03ZDFiLTQ4MDctYmZiYy1kZjgzZjQyNDk2NDUifQ.noQfh7IRPZKl5yZb7GtrNwz1rGoPzrn0C2gnZRZEw-gf5_J9qzkGcuslJ-J8Ew8FUU6rDvA6bVCje9iTXhSveQ'
            monitor_logger.warning("⚠️ 使用静态 DPoP Token，建议启用自动刷新功能")
        
        # 构建请求头
        if self.use_random_ua:
            # 使用随机 User-Agent 管理器
            ua_data = default_ua_manager.get_current_ua_data()
            self.headers = {
                'Content-Type': 'application/json',
                **ua_data['headers']  # 使用协同的头部
            }
            monitor_logger.info(f"🎲 使用随机 User-Agent: {ua_data['user_agent'][:50]}...")
        else:
            # 使用固定 User-Agent
            fixed_ua = user_agent or 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36'
            self.headers = {
                'Content-Type': 'application/json',
                'User-Agent': fixed_ua,
                'Accept': 'application/json, text/plain, */*',
                'Accept-Encoding': 'gzip, deflate, br, zstd',
                'Accept-Language': 'ja',
                'Origin': 'https://jp.mercari.com',
                'Referer': 'https://jp.mercari.com/',
                'Sec-Ch-Ua': '"Not)A;Brand";v="8", "Chromium";v="138", "Google Chrome";v="138"',
                'Sec-Ch-Ua-Mobile': '?0',
                'Sec-Ch-Ua-Platform': '"Windows"',
                'Sec-Fetch-Dest': 'empty',
                'Sec-Fetch-Mode': 'cors',
                'Sec-Fetch-Site': 'cross-site',
                'X-Country-Code': 'KR',
                'X-Platform': 'web',
                'priority': 'u=1, i'
            }
            monitor_logger.info(f"🔧 使用固定 User-Agent: {fixed_ua[:50]}...")
        
        # 添加DPoP令牌到请求头
        if self.dpop_token:
            self.headers['DPoP'] = self.dpop_token
            
        # 创建会话
        self.session = requests.Session()
        self.session.headers.update(self.headers)

        # 添加重试机制和连接池配置
        from requests.adapters import HTTPAdapter
        from urllib3.util.retry import Retry

        # 配置重试策略
        retry_strategy = Retry(
            total=3,
            backoff_factor=1,
            status_forcelist=[429, 500, 502, 503, 504],
        )

        # 配置HTTP适配器
        adapter = HTTPAdapter(
            max_retries=retry_strategy,
            pool_connections=10,
            pool_maxsize=20,
            pool_block=False
        )

        self.session.mount('https://', adapter)
        self.session.mount('http://', adapter)

    def _estimate_request_size(self, url: str, method: str = "GET", data: Optional[Dict] = None, params: Optional[Dict] = None) -> int:
        """估算请求大小"""
        size = len(url.encode('utf-8'))

        # 估算headers大小
        for k, v in self.headers.items():
            size += len(f"{k}: {v}\r\n".encode('utf-8'))

        # 估算请求数据
        if data:
            size += len(json.dumps(data).encode('utf-8'))

        # 估算查询参数
        if params:
            param_str = "&".join([f"{k}={v}" for k, v in params.items()])
            size += len(param_str.encode('utf-8'))

        return size + 200  # 加上HTTP协议开销

    def _record_traffic(self, url: str, method: str, request_size: int, response_size: int, success: bool, task_type: str = "mercari_api"):
        """记录流量统计（同步版本）- 修复为直接调用同步方法"""
        monitor_logger.debug(f"🔍 开始记录流量: {method} {url[:50]}... | 请求:{request_size}B 响应:{response_size}B")

        try:
            # 直接调用同步的流量统计方法
            traffic_monitor.record_traffic_sync(
                proxy_url=None,  # 当前没有使用代理
                request_size=request_size,
                response_size=response_size,
                task_type=task_type,
                success=success,
                url=url
            )
            monitor_logger.debug(f"✅ 同步流量统计完成")

        except Exception as e:
            # 流量统计失败不应影响主业务
            monitor_logger.warning(f"❌ 流量统计记录失败: {e}")
            import traceback
            monitor_logger.debug(f"❌ 流量统计错误堆栈: {traceback.format_exc()}")

    def _ensure_valid_token(self) -> None:
        """确保 DPoP Token 有效，如果过期则自动刷新"""
        if not self.auto_refresh_token or not DPOP_GENERATOR_AVAILABLE:
            return

        try:
            if self.dpop_token and is_mercari_token_expired(self.dpop_token):
                monitor_logger.info("🔄 DPoP Token 已过期，正在自动刷新...")
                old_token = self.dpop_token[:20] + "..."
                self.dpop_token = get_fresh_mercari_token()
                self.headers['DPoP'] = self.dpop_token
                self.session.headers.update(self.headers)
                monitor_logger.info(f"✅ DPoP Token 刷新成功: {old_token} -> {self.dpop_token[:20]}...")
            elif not self.dpop_token:
                monitor_logger.info("🔄 DPoP Token 为空，正在生成新的 Token...")
                self.dpop_token = get_fresh_mercari_token()
                self.headers['DPoP'] = self.dpop_token
                self.session.headers.update(self.headers)
                monitor_logger.info("✅ 新的 DPoP Token 生成完成")
        except Exception as e:
            monitor_logger.error(f"❌ DPoP Token 刷新失败: {e}")
            # 刷新失败时继续使用现有 Token
    
    def _ensure_valid_user_agent(self) -> None:
        """确保 User-Agent 有效，如果需要则自动刷新"""
        if not self.use_random_ua:
            return
        
        try:
            # 检查是否需要刷新 User-Agent
            if default_ua_manager.should_refresh():
                monitor_logger.info("🔄 User-Agent 需要刷新，正在更新...")
            
            # 获取当前 UA 数据（如果需要会自动刷新）
            ua_data = default_ua_manager.get_current_ua_data()
            
            # 检查当前 UA 是否与管理器中的一致
            current_ua = self.headers.get('User-Agent', '')
            manager_ua = ua_data['user_agent']
            
            if current_ua != manager_ua:
                monitor_logger.info(f"🔄 更新 User-Agent: {manager_ua[:50]}...")
                
                # 更新请求头，保留 Content-Type 和 DPoP
                content_type = self.headers.get('Content-Type')
                dpop_token = self.headers.get('DPoP')
                
                self.headers = {
                    'Content-Type': content_type,
                    **ua_data['headers']
                }
                
                # 重新添加 DPoP Token
                if dpop_token:
                    self.headers['DPoP'] = dpop_token
                
                # 更新会话头部
                self.session.headers.update(self.headers)
                
                monitor_logger.info(f"✅ User-Agent 更新成功: {ua_data['user_agent'][:50]}...")
        except Exception as e:
            monitor_logger.error(f"❌ User-Agent 刷新失败: {e}")
            # 刷新失败时继续使用现有 User-Agent
    
    def get_ua_status(self) -> Dict[str, any]:
        """获取 User-Agent 状态信息"""
        if not self.use_random_ua:
            return {
                'mode': 'fixed',
                'current_ua': self.headers.get('User-Agent', 'Unknown')[:50] + '...'
            }
        
        ua_status = default_ua_manager.get_status()
        ua_status['mode'] = 'random'
        return ua_status
    
    @log_function_call("mercari")
    def search_products(self, keyword: str, sort: str = 'SORT_CREATED_TIME',
                       order: str = 'ORDER_DESC', limit: int = 20) -> Optional[Dict]:
        """
        搜索Mercari商品
        
        Args:
            keyword: 搜索关键词
            sort: 排序字段，默认为'SORT_CREATED_TIME'（按创建时间排序）
            order: 排序方向，默认为'ORDER_DESC'（降序）
            limit: 结果数量，默认为20
            
        Returns:
            搜索结果字典或None（如果失败）
        """
        endpoint = '/v2/entities:search'
        url = f'{self.base_url}{endpoint}'
        
        # 构建完整的payload
        payload = {
            "userId": "",
            "pageSize": limit,
            "pageToken": "",
            "searchSessionId": f"{int(time.time())}{hashlib.md5(keyword.encode()).hexdigest()[:8]}",
            "source": "BaseSerp",
            "indexRouting": "INDEX_ROUTING_UNSPECIFIED",
            "thumbnailTypes": [],
            "searchCondition": {
                "keyword": keyword,
                "excludeKeyword": "",
                "sort": sort,
                "order": order,
                "status": [],
                "sizeId": [],
                "categoryId": [],
                "brandId": [],
                "sellerId": [],
                "priceMin": 0,
                "priceMax": 0,
                "itemConditionId": [],
                "shippingPayerId": [],
                "shippingFromArea": [],
                "shippingMethod": [],
                "colorId": [],
                "hasCoupon": False,
                "attributes": [],
                "itemTypes": [],
                "skuIds": [],
                "shopIds": [],
                "excludeShippingMethodIds": []
            },
            "serviceFrom": "suruga",
            "withItemBrand": True,
            "withItemSize": False,
            "withItemPromotions": False,
            "withItemSizes": False,
            "withShopname": False,
            "useDynamicAttribute": False,
            "withSuggestedItems": False,
            "withOfferPricePromotion": False,
            "withProductSuggest": False,
            "withParentProducts": False,
            "withProductArticles": False,
            "withSearchConditionId": False,
            "withAuction": False,
            "laplaceDeviceUuid": "6bfeff14dad2abab10fc65a0f2a79f85"
        }
        
        try:
            # 确保 DPoP Token 有效
            self._ensure_valid_token()
            
            # 确保 User-Agent 有效
            self._ensure_valid_user_agent()

            # 计算请求大小（未压缩）
            request_size = self._estimate_request_size(url, "POST", data=payload)

            response = self.session.post(url, json=payload, timeout=10)
            response.raise_for_status()

            result = response.json()

            # 计算响应大小
            response_size = len(response.content)

            # 统计搜索结果
            product_count = 0
            if 'items' in result:
                product_count = len(result['items'])

            # 记录流量统计
            self._record_traffic(url, "POST", request_size, response_size, True, "mercari_search")

            return result

        except requests.exceptions.HTTPError as e:
            # 记录失败的流量统计
            request_size = self._estimate_request_size(url, "POST", data=payload)
            response_size = len(response.content) if 'response' in locals() and response else 0
            self._record_traffic(url, "POST", request_size, response_size, False, "mercari_search")

            monitor_logger.error(f'❌ Mercari API HTTP错误: {e}，状态码: {response.status_code if "response" in locals() else "未知"}')
            if 'response' in locals() and response:
                monitor_logger.error(f'错误响应内容: {response.text[:300]}...')
                if response.status_code == 400:
                    monitor_logger.error('请求格式错误，请检查请求参数和格式')
                elif response.status_code == 401:
                    monitor_logger.error('认证错误，可能需要更新DPoP令牌或其他认证信息')
                    # 如果是认证错误，尝试刷新 Token
                    if self.auto_refresh_token and DPOP_GENERATOR_AVAILABLE:
                        monitor_logger.info("🔄 检测到认证错误，尝试强制刷新 DPoP Token...")
                        try:
                            self.dpop_token = get_fresh_mercari_token()
                            self.headers['DPoP'] = self.dpop_token
                            self.session.headers.update(self.headers)
                            monitor_logger.info("✅ DPoP Token 强制刷新完成，请重试请求")
                        except Exception as refresh_error:
                            monitor_logger.error(f"❌ 强制刷新 DPoP Token 失败: {refresh_error}")
                elif response.status_code == 403:
                    monitor_logger.error('权限错误，可能需要更新DPoP令牌或检查认证信息')
            return None

        except requests.exceptions.RequestException as e:
            # 记录失败的流量统计
            request_size = self._estimate_request_size(url, "POST", data=payload)
            self._record_traffic(url, "POST", request_size, 0, False, "mercari_search")

            monitor_logger.error(f'❌ Mercari API请求异常: {e}')
            return None

        except json.JSONDecodeError as e:
            monitor_logger.error(f'❌ Mercari API JSON解析错误: {e}')
            if 'response' in locals() and response:
                monitor_logger.error(f'响应内容: {response.text[:300]}...')
            return None
    
    def parse_products(self, api_response: Dict) -> List[Dict]:
        """
        解析API响应，提取商品信息

        Args:
            api_response: Mercari API响应

        Returns:
            商品信息列表，每个商品包含id、name、price、url等字段
        """
        products = []

        if not api_response:
            monitor_logger.warning("API响应为空")
            return products

        # 调试：打印API响应结构
        monitor_logger.debug(f"API响应键: {list(api_response.keys()) if isinstance(api_response, dict) else 'Not a dict'}")

        # 尝试不同的可能的数据结构
        items = None
        if 'items' in api_response:
            items = api_response['items']
        elif 'data' in api_response and isinstance(api_response['data'], dict) and 'items' in api_response['data']:
            items = api_response['data']['items']
        elif 'results' in api_response:
            items = api_response['results']

        if not items:
            monitor_logger.warning("API响应中没有找到商品数据")
            monitor_logger.debug(f"完整API响应: {str(api_response)[:500]}...")
            return products

        # monitor_logger.info(f"找到 {len(items)} 个商品项目")

        for i, item in enumerate(items):
            try:
                # 检查item是否为字典
                if not isinstance(item, dict):
                    monitor_logger.warning(f"商品项目 {i} 不是字典类型: {type(item)}")
                    continue

                # 获取图片URL - 优先使用photos字段，fallback到thumbnails
                image_url = None
                if item.get("photos") and len(item["photos"]) > 0:
                    # photos格式: [{"uri": "https://..."}]
                    image_url = item["photos"][0].get("uri")
                elif item.get("thumbnails") and len(item["thumbnails"]) > 0:
                    # thumbnails格式: ["https://..."]
                    image_url = item["thumbnails"][0]

                # 根据实际API响应结构解析商品信息
                product = {
                    "id": item.get("id"),
                    "name": item.get("name"),
                    "price": int(item.get("price", 0)) if item.get("price") and item.get("price").isdigit() else 0,
                    "url": f"https://jp.mercari.com/item/{item.get('id')}" if item.get('id') else None,
                    "image_url": image_url,
                    "seller_id": item.get("sellerId"),
                    "condition_id": item.get("itemConditionId"),
                    "status": item.get("status"),
                    "created_time": item.get("created"),
                    "updated_time": item.get("updated"),
                    "category_id": item.get("categoryId"),
                    "shipping_payer_id": item.get("shippingPayerId"),
                    "photos": item.get("photos", [])
                }
                products.append(product)

            except Exception as e:
                monitor_logger.warning(f"⚠️ 解析商品信息失败 (项目 {i}): {e}")
                monitor_logger.debug(f"问题项目内容: {str(item)[:200]}...")
                continue

        # monitor_logger.info(f"📦 成功解析 {len(products)} 个商品")
        return products
    
    def _generate_seller_dpop_token(self, url: str, method: str = "GET") -> Optional[str]:
        """
        为卖家API生成特定的DPoP Token

        Args:
            url: 请求URL
            method: HTTP方法

        Returns:
            DPoP Token字符串或None
        """
        try:
            if DPOP_GENERATOR_AVAILABLE:
                # 使用DPoP生成器为特定URL生成Token
                from .dpop_token_generator import default_dpop_generator
                dpop_token = default_dpop_generator.generate_dpop_token(
                    http_method=method,
                    http_uri=url,
                    expires_in=300  # 5分钟有效期，适合卖家API
                )
                monitor_logger.debug(f"🔑 为卖家API生成专用DPoP Token: {url}")
                return dpop_token
            else:
                monitor_logger.warning("DPoP生成器不可用，无法为卖家API生成专用Token")
                return None
        except Exception as e:
            monitor_logger.error(f"❌ 生成卖家API DPoP Token失败: {e}")
            return None

    @log_function_call("mercari")
    def get_seller_products(self, seller_id: str, limit: int = 30,
                           with_auction: bool = False, status: str = "on_sale") -> Optional[Dict]:
        """
        根据卖家ID获取商品列表

        Args:
            seller_id: 卖家ID
            limit: 结果数量，默认为30
            with_auction: 是否包含拍卖商品，默认为False
            status: 商品状态，默认为"on_sale"（在售）

        Returns:
            卖家商品列表响应字典或None（如果失败）
        """
        endpoint = '/items/get_items'
        url = f'{self.base_url}{endpoint}'

        # 构建查询参数
        params = {
            'seller_id': seller_id,
            'limit': limit,
            'with_auction': str(with_auction).lower(),
            'status': status
        }

        try:
            # monitor_logger.info(f'🔍 获取卖家商品: seller_id={seller_id}, limit={limit}, status={status}')
            
            # 确保 User-Agent 有效
            self._ensure_valid_user_agent()

            # 为卖家API生成专用的DPoP Token
            seller_dpop_token = self._generate_seller_dpop_token(url, "GET")

            # 创建专用的请求头，使用当前的 User-Agent 设置
            if self.use_random_ua:
                # 使用随机 UA 的协同头部
                ua_data = default_ua_manager.get_current_ua_data()
                seller_headers = {
                    **ua_data['headers'],
                    'X-Platform': 'web'
                }
            else:
                # 使用固定 UA
                seller_headers = {
                    'Accept': 'application/json, text/plain, */*',
                    'Accept-Encoding': 'gzip, deflate, br, zstd',
                    'Accept-Language': 'ja',
                    'Origin': 'https://jp.mercari.com',
                    'Referer': 'https://jp.mercari.com/',
                    'Sec-Ch-Ua': '"Chromium";v="122", "Not(A:Brand";v="24", "Google Chrome";v="122"',
                    'Sec-Ch-Ua-Mobile': '?0',
                    'Sec-Ch-Ua-Platform': '"Windows"',
                    'Sec-Fetch-Dest': 'empty',
                    'Sec-Fetch-Mode': 'cors',
                    'Sec-Fetch-Site': 'cross-site',
                    'User-Agent': self.headers.get('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36'),
                    'X-Platform': 'web'
                }
            # monitor_logger.info(f"查看当前ua:{seller_headers}")
            # 添加DPoP Token
            if seller_dpop_token:
                seller_headers['DPoP'] = seller_dpop_token
                monitor_logger.debug("✅ 使用专用DPoP Token进行卖家API请求")
            else:
                monitor_logger.warning("⚠️ 无法生成专用DPoP Token，使用通用Token")
                seller_headers['DPoP'] = self.dpop_token

            # 计算请求大小
            request_size = self._estimate_request_size(url, "GET", params=params)

            # 发送请求
            response = requests.get(url, params=params, headers=seller_headers, timeout=10)

            # 检查响应状态
            if response.status_code == 401:
                monitor_logger.warning(f'⚠️ 卖家商品API认证失败 (401)')
                monitor_logger.info(f'🔄 尝试使用通用DPoP Token重试...')

                # 尝试使用通用Token重试
                seller_headers['DPoP'] = self.dpop_token
                response = requests.get(url, params=params, headers=seller_headers, timeout=10)

                if response.status_code == 401:
                    monitor_logger.error(f'❌ 使用通用Token仍然认证失败')
                    # 记录失败的流量统计
                    response_size = len(response.content) if response else 0
                    self._record_traffic(url, "GET", request_size, response_size, False, "mercari_seller")
                    return None

            response.raise_for_status()
            result = response.json()

            # 计算响应大小并记录流量统计
            response_size = len(response.content)
            self._record_traffic(url, "GET", request_size, response_size, True, "mercari_seller")

            # 统计商品数量
            product_count = 0
            if 'data' in result and isinstance(result['data'], list):
                product_count = len(result['data'])

            # monitor_logger.info(f'✅ 卖家商品API调用成功，状态码: {response.status_code}，获取商品数量: {product_count}')
            return result

        except requests.exceptions.HTTPError as e:
            # 记录失败的流量统计
            request_size = self._estimate_request_size(url, "GET", params=params)
            response_size = len(response.content) if 'response' in locals() and response else 0
            self._record_traffic(url, "GET", request_size, response_size, False, "mercari_seller")

            monitor_logger.error(f'❌ 卖家商品API HTTP错误: {e}，状态码: {response.status_code if "response" in locals() else "未知"}')
            if 'response' in locals() and response:
                monitor_logger.error(f'错误响应内容: {response.text[:300]}...')
                if response.status_code == 400:
                    monitor_logger.error('请求格式错误，请检查seller_id参数')
                elif response.status_code == 401:
                    monitor_logger.error('认证错误')
                    return None
                elif response.status_code == 403:
                    monitor_logger.error('权限错误，可能需要更新DPoP令牌或检查认证信息')
                elif response.status_code == 404:
                    monitor_logger.error(f'卖家不存在或无商品: seller_id={seller_id}')
            return None

        except requests.exceptions.RequestException as e:
            # 记录失败的流量统计
            request_size = self._estimate_request_size(url, "GET", params=params)
            self._record_traffic(url, "GET", request_size, 0, False, "mercari_seller")

            monitor_logger.error(f'❌ 卖家商品API请求异常: {e}')
            return None

        except json.JSONDecodeError as e:
            monitor_logger.error(f'❌ 卖家商品API JSON解析错误: {e}')
            if 'response' in locals() and response:
                monitor_logger.error(f'响应内容: {response.text[:300]}...')
            return None



    def parse_seller_products(self, api_response: Dict) -> List[Dict]:
        """
        解析卖家商品API响应，提取商品信息

        Args:
            api_response: 卖家商品API响应

        Returns:
            商品信息列表，每个商品包含id、name、price、url等字段
        """
        products = []

        if not api_response:
            monitor_logger.warning("卖家商品API响应为空")
            return products

        # 调试：打印API响应结构
        # monitor_logger.debug(f"卖家商品API响应键: {list(api_response.keys()) if isinstance(api_response, dict) else 'Not a dict'}")

        # 检查响应状态
        if api_response.get('result') != 'OK':
            monitor_logger.warning(f"卖家商品API响应状态异常: {api_response.get('result')}")
            return products

        # 获取商品数据
        items = api_response.get('data', [])
        if not items:
            monitor_logger.warning("卖家商品API响应中没有找到商品数据")
            return products

        # monitor_logger.info(f"找到 {len(items)} 个卖家商品")

        for i, item in enumerate(items):
            try:
                # 检查item是否为字典
                if not isinstance(item, dict):
                    monitor_logger.warning(f"卖家商品项目 {i} 不是字典类型: {type(item)}")
                    continue

                # 获取图片URL - 卖家API使用thumbnails字段
                image_url = None
                if item.get("thumbnails") and len(item["thumbnails"]) > 0:
                    # thumbnails格式: ["https://..."]
                    image_url = item["thumbnails"][0]

                # 根据卖家商品API响应结构解析商品信息
                product = {
                    "id": item.get("id"),
                    "name": item.get("name"),
                    "price": item.get("price", 0),
                    "url": f"https://jp.mercari.com/item/{item.get('id')}" if item.get('id') else None,
                    "image_url": image_url,
                    "seller_id": item.get("seller", {}).get("id") if item.get("seller") else None,
                    "seller_name": item.get("seller", {}).get("name") if item.get("seller") else None,
                    "status": item.get("status"),
                    "created_time": item.get("created"),
                    "updated_time": item.get("updated"),
                    "category_id": item.get("item_category_ntiers", {}).get("id") if item.get("item_category_ntiers") else None,
                    "category_name": item.get("item_category_ntiers", {}).get("name") if item.get("item_category_ntiers") else None,
                    "root_category_id": item.get("item_category_ntiers", {}).get("root_category_id") if item.get("item_category_ntiers") else None,
                    "root_category_name": item.get("item_category_ntiers", {}).get("root_category_name") if item.get("item_category_ntiers") else None,
                    "num_likes": item.get("num_likes", 0),
                    "num_comments": item.get("num_comments", 0),
                    "shipping_from_area": item.get("shipping_from_area", {}).get("name") if item.get("shipping_from_area") else None,
                    "shipping_method_id": item.get("shipping_method_id"),
                    "pager_id": item.get("pager_id")
                }
                products.append(product)

            except Exception as e:
                monitor_logger.warning(f"⚠️ 解析卖家商品信息失败 (项目 {i}): {e}")
                monitor_logger.debug(f"问题项目内容: {str(item)[:200]}...")
                continue

        # monitor_logger.info(f"📦 成功解析 {len(products)} 个卖家商品")
        return products

    @log_function_call("mercari")
    def get_seller_products_and_parse(self, seller_id: str, **kwargs) -> List[Dict]:
        """
        获取并解析卖家商品的便捷方法

        Args:
            seller_id: 卖家ID
            **kwargs: 传递给get_seller_products的其他参数

        Returns:
            解析后的商品信息列表
        """
        try:
            monitor_logger.debug(f"🔍 开始获取卖家商品: seller_id='{seller_id}'")
            api_response = self.get_seller_products(seller_id, **kwargs)

            if api_response:
                # monitor_logger.debug(f"✅ 卖家商品API响应成功，开始解析商品数据")
                products = self.parse_seller_products(api_response)
                # monitor_logger.info(f"📦 卖家商品解析完成: 成功解析{len(products)}个商品")
                return products
            else:
                monitor_logger.warning(f"⚠️ 卖家商品API响应为空: seller_id='{seller_id}'")
                return []

        except Exception as e:
            monitor_logger.error(f"❌ 卖家商品获取解析异常: {e}, seller_id='{seller_id}'")
            return []

    @log_function_call("mercari")
    def get_shop_products(self, product_id: str, limit: int = 30) -> Optional[Dict]:
        """
        根据商品ID获取店铺商品列表

        注意：这个API实际上是通过一个商品ID来获取该商品所属店铺的所有商品
        shop_id参数实际上应该是一个该店铺的商品ID

        Args:
            product_id: 店铺中的一个商品ID（用于获取店铺信息）
            limit: 结果数量，默认为30

        Returns:
            店铺商品列表响应字典或None（如果失败）
        """
        # 构建URL - 使用商品ID来获取店铺信息，然后从shopItems中提取商品
        endpoint = f'/v1/marketplaces/shops/products/{product_id}'
        url = f'{self.base_url}{endpoint}'

        # 构建查询参数
        params = {
            'view': 'FULL',
            'imageType': 'JPEG'
        }

        try:
            # monitor_logger.info(f'🔍 获取店铺商品: product_id={product_id}, limit={limit}')
            
            # 确保 User-Agent 有效
            self._ensure_valid_user_agent()

            # 为店铺API生成专用的DPoP Token
            shop_dpop_token = self._generate_shop_dpop_token(url, "GET")

            # 计算请求大小
            request_size = self._estimate_request_size(url, "GET", params=params)

            # 设置请求头
            headers = self.headers.copy()
            if shop_dpop_token:
                headers['DPoP'] = shop_dpop_token
                monitor_logger.debug(f"✅ 已添加店铺DPoP令牌: {shop_dpop_token[:30]}...")

            # 发送GET请求
            response = self.session.get(url, params=params, headers=headers, timeout=10)

            monitor_logger.debug(f'📥 店铺API响应状态码: {response.status_code}')

            if response.status_code != 200:
                monitor_logger.warning(f'📄 店铺API响应头: {dict(response.headers)}')
                monitor_logger.warning(f'📝 店铺API响应内容: {response.text[:500]}...')
                # 记录失败的流量统计
                response_size = len(response.content) if response else 0
                self._record_traffic(url, "GET", request_size, response_size, False, "mercari_shop")
                return None

            result = response.json()

            # 计算响应大小并记录流量统计
            response_size = len(response.content)
            self._record_traffic(url, "GET", request_size, response_size, True, "mercari_shop")

            # 统计店铺商品结果
            shop_items_count = 0
            if 'productDetail' in result and 'shop' in result['productDetail'] and 'shopItems' in result['productDetail']['shop']:
                shop_items_count = len(result['productDetail']['shop']['shopItems'])

            # monitor_logger.info(f'✅ 店铺API调用成功，状态码: {response.status_code}，获取店铺商品数量: {shop_items_count}')
            return result

        except requests.exceptions.RequestException as e:
            # 记录失败的流量统计
            request_size = self._estimate_request_size(url, "GET", params=params)
            self._record_traffic(url, "GET", request_size, 0, False, "mercari_shop")

            monitor_logger.error(f'❌ 店铺API请求异常: {e}, product_id={product_id}')
            return None
        except Exception as e:
            # 记录失败的流量统计
            request_size = self._estimate_request_size(url, "GET", params=params)
            self._record_traffic(url, "GET", request_size, 0, False, "mercari_shop")

            monitor_logger.error(f'❌ 店铺API处理异常: {e}, product_id={product_id}')
            return None

    def _generate_shop_dpop_token(self, url: str, method: str) -> Optional[str]:
        """
        为店铺API生成DPoP Token

        Args:
            url: 请求URL
            method: HTTP方法

        Returns:
            DPoP Token字符串或None
        """
        try:
            if DPOP_GENERATOR_AVAILABLE:
                from app.utils.dpop_token_generator import DPoPTokenGenerator
                # 创建临时生成器实例为特定URL生成Token
                generator = DPoPTokenGenerator()
                return generator.generate_dpop_token(
                    http_method=method,
                    http_uri=url,
                    expires_in=3600  # 1小时有效期
                )
            else:
                monitor_logger.warning("DPoP Token生成器不可用，使用默认Token")
                return self.dpop_token
        except Exception as e:
            monitor_logger.error(f"生成店铺DPoP Token失败: {e}")
            return self.dpop_token

    @log_function_call("mercari")
    def search_and_parse(self, keyword: str, **kwargs) -> List[Dict]:
        """
        搜索并解析商品的便捷方法

        Args:
            keyword: 搜索关键词
            **kwargs: 传递给search_products的其他参数

        Returns:
            解析后的商品信息列表
        """
        try:
            # monitor_logger.debug(f"🔍 开始搜索煤炉商品: 关键词='{keyword}'")
            api_response = self.search_products(keyword, **kwargs)

            if api_response:
                # monitor_logger.debug(f"✅ 煤炉API响应成功，开始解析商品数据")
                products = self.parse_products(api_response)
                # monitor_logger.info(f"📦 煤炉商品解析完成: 成功解析{len(products)}个商品")
                return products
            else:
                monitor_logger.warning(f"⚠️ 煤炉API响应为空: 关键词='{keyword}'")
                return []

        except Exception as e:
            monitor_logger.error(f"❌ 煤炉商品搜索解析异常: {e}, 关键词='{keyword}'")
            return []

    def parse_shop_products(self, api_response: Dict) -> List[Dict]:
        """
        解析店铺商品API响应，提取商品信息

        Args:
            api_response: 店铺商品API响应

        Returns:
            商品信息列表，每个商品包含id、name、price、url等字段
        """
        products = []

        if not api_response:
            monitor_logger.warning("店铺商品API响应为空")
            return products

        # 调试：打印API响应结构
        # monitor_logger.debug(f"店铺商品API响应键: {list(api_response.keys()) if isinstance(api_response, dict) else 'Not a dict'}")

        # 获取店铺商品数据
        try:
            product_detail = api_response.get('productDetail', {})
            shop_info = product_detail.get('shop', {})
            shop_items = shop_info.get('shopItems', [])

            if not shop_items:
                monitor_logger.warning("店铺商品API响应中没有找到shopItems数据")
                return products

            # monitor_logger.info(f"找到 {len(shop_items)} 个店铺商品")

            # 解析每个商品
            for item in shop_items:
                try:
                    product_id = item.get('productId', '')
                    if not product_id:
                        monitor_logger.warning("商品缺少productId，跳过")
                        continue

                    # 获取并清理图片URL
                    thumbnail_url = item.get('thumbnail', '')
                    # 清理shop图片URL的@jpg后缀（Mercari shop特有格式）
                    clean_thumbnail = thumbnail_url.replace('@jpg', '') if thumbnail_url else ''

                    # 构建商品信息
                    product = {
                        'id': product_id,
                        'name': item.get('displayName', ''),
                        'price': int(item.get('price', 0)) if item.get('price') else 0,
                        'url': f'https://jp.mercari.com/item/{product_id}',
                        'thumbnail': clean_thumbnail,  # 清理后的图片URL
                        'image_url': clean_thumbnail,  # 映射到image_url供邮件模板使用
                        'tags': item.get('productTags', []),
                        'is_sold_out': 'sold_out' in item.get('productTags', []),
                        'source': 'shop',
                        'shop_id': shop_info.get('name', ''),
                        'shop_name': shop_info.get('displayName', ''),
                        'shop_thumbnail': shop_info.get('thumbnail', '').replace('@jpg', '') if shop_info.get('thumbnail') else '',
                        'created_time': None,  # 店铺商品API不提供创建时间
                        'updated_time': None   # 店铺商品API不提供更新时间
                    }

                    products.append(product)
                    # monitor_logger.debug(f"✅ 解析店铺商品: {product['name']} (¥{product['price']})")

                except Exception as e:
                    monitor_logger.error(f"❌ 解析单个店铺商品失败: {e}")
                    continue

        except Exception as e:
            monitor_logger.error(f"❌ 解析店铺商品响应失败: {e}")

        # monitor_logger.info(f"📦 店铺商品解析完成: 成功解析{len(products)}个商品")
        return products

    @log_function_call("mercari")
    def get_shop_products_and_parse(self, product_id: str, **kwargs) -> List[Dict]:
        """
        获取并解析店铺商品的便捷方法

        Args:
            product_id: 店铺中的一个商品ID（用于获取店铺信息）
            **kwargs: 传递给get_shop_products的其他参数

        Returns:
            解析后的商品信息列表
        """
        try:
            # monitor_logger.debug(f"🔍 开始获取店铺商品: product_id='{product_id}'")
            api_response = self.get_shop_products(product_id, **kwargs)

            if api_response:
                monitor_logger.debug(f"✅ 店铺商品API响应成功，开始解析商品数据")
                products = self.parse_shop_products(api_response)
                # monitor_logger.info(f"📦 店铺商品解析完成: 成功解析{len(products)}个商品")
                return products
            else:
                monitor_logger.warning(f"⚠️ 店铺商品API响应为空: product_id='{product_id}'")
                return []

        except Exception as e:
            monitor_logger.error(f"❌ 店铺商品获取解析异常: {e}, product_id='{product_id}'")
            return []


# 懒加载默认实例，避免在 Celery Beat/导入阶段就初始化并产生日志
_default_mercari_client: Optional[MercariAPI] = None

def get_default_mercari_client() -> MercariAPI:
    global _default_mercari_client
    if _default_mercari_client is None:
        _default_mercari_client = MercariAPI(auto_refresh_token=True, use_random_ua=True)
    return _default_mercari_client


@log_function_call("mercari")
def search_mercari_products(keyword: str, **kwargs) -> List[Dict]:
    """
    便捷函数：搜索Mercari商品

    Args:
        keyword: 搜索关键词
        **kwargs: 其他搜索参数

    Returns:
        商品信息列表
    """
    return get_default_mercari_client().search_and_parse(keyword, **kwargs)


@log_function_call("mercari")
def get_mercari_seller_products(seller_id: str, **kwargs) -> List[Dict]:
    """
    便捷函数：根据卖家ID获取Mercari商品

    Args:
        seller_id: 卖家ID
        **kwargs: 其他参数（limit, with_auction, status等）

    Returns:
        商品信息列表
    """
    return get_default_mercari_client().get_seller_products_and_parse(seller_id, **kwargs)


@log_function_call("mercari")
def get_mercari_shop_products(product_id: str, **kwargs) -> List[Dict]:
    """
    便捷函数：根据商品ID获取Mercari店铺商品

    Args:
        product_id: 店铺中的一个商品ID（用于获取店铺信息）
        **kwargs: 其他参数（limit等）

    Returns:
        商品信息列表
    """
    return get_default_mercari_client().get_shop_products_and_parse(product_id, **kwargs)
